/*
 * HttpTsMediaCaster.cpp
 *
 *  Created on: 2019年2月28日
 *      Author: terry
 */

#include "HttpTsMediaCaster.h"
#include "HttpMediaCasterConnection.h"


namespace av
{

HttpTsMediaCaster::HttpTsMediaCaster()
{
}

HttpTsMediaCaster::~HttpTsMediaCaster()
{
    close();
}

int HttpTsMediaCaster::open(const std::string& ip, uint16_t port, const MediaFormat& fmt)
{
    if (!TcpServer::start(ip.c_str(), port))
    {
        return ENOENT;
    }

    openMuxer(fmt);

    return 0;
}

void HttpTsMediaCaster::close()
{
    TcpServer::stop();

    closeMuxer();
    m_format.clear();
}

bool HttpTsMediaCaster::isOpen()
{
    return TcpServer::isStarted();
}

void HttpTsMediaCaster::writePacket(uint8_t* data, int size, int64_t pts, int flags)
{
    MediaPacketPtr packet(new MediaPacket());

    char chunk_size[64] = {0};
    int n = snprintf(chunk_size, sizeof(chunk_size), "%lX\r\n", (unsigned long)size);
    char chunk_end[4] = {0};
    memcpy(chunk_end, "\r\n", 2);

    packet->ensure(size + n + 4);
    packet->write((uint8_t*)chunk_size, n);
    packet->write(data, size);
    packet->write((uint8_t*)chunk_end, 2);

    packet->flags = flags;
    packet->pts = pts;

    writeMediaPacket(packet);
}

void HttpTsMediaCaster::closeAll()
{
    TcpServer::closeAll();
}

void HttpTsMediaCaster::removeAllTarget()
{
    BasicTsMediaCaster::removeAllTarget();
    closeAll();
}

void HttpTsMediaCaster::writeMediaPacket(MediaPacketPtr& pkt)
{
    auto func = [&](evutil_socket_t s, TcpConnectionPtr& connection)
    {
        dispatchPacket(connection, pkt);
        return true;
    };

    m_connMap.forEach(func);
}

TcpConnectionPtr HttpTsMediaCaster::create(evutil_socket_t fd)
{
    fireEvent(CASTER_SESSION_CREATE);

    HttpMediaCasterConnection* conn = new HttpMediaCasterConnection();

    conn->onMediaFormat(m_format);

    return TcpConnectionPtr(conn);
}

void HttpTsMediaCaster::onClose(TcpConnectionPtr& conn)
{
    fireEvent(CASTER_SESSION_DESTROY);

}


void HttpTsMediaCaster::dispatchPacket(TcpConnectionPtr& connection, MediaPacketPtr& pkt)
{
    HttpMediaCasterConnection* casterConnection = dynamic_cast<HttpMediaCasterConnection*>(connection.get());
    casterConnection->onMediaPacket(pkt);
}



} /* namespace av */

